package com;

import com.mycanvas.AllPv;
import com.mycanvas.FontTable;
import com.mycanvas.Pv;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ExampleParseAlabo {

    public static byte[] bytes;//字库
    public static List<AllPv> allPvList = new ArrayList<>();

    public static void main(String[] argv) {
        FileInputStream inputStream = null;
        try {
            System.out.println(System.getProperty("user.dir"));
            inputStream = new FileInputStream("./lib/font/Arabic7.ara");
            int size = inputStream.available();
            bytes = new byte[size];
            inputStream.read(bytes);
            inputStream.close();

            //all 32~88   child 0~4

            //all show
            for (int i = 32; i < 88; i++) {
                for (int j = 0; j < 4; j++) {
                    byte[] data = getCharData(bytes, i, j);
                    if (data[0] != 0) {
                        addPoint(data, i, j);
                    }
                }
            }

            //0原 1头 2中 3尾
//            String str = "كومبيوتر";
//            String[] strArray = str.trim().split(" ");
//            FormatUtils.reverseArray(strArray);
//            for (int i = 0; i < strArray.length; i++) {
//                char[] chars = strArray[i].toCharArray();
//                if (chars.length == 1) {
//                    String valueStr = FormatUtils.bcd2Str(FormatUtils.charToByte(chars[0]));
//                    Integer fontIndex = FontTable.alaboTable.get(valueStr);
//                    if (getAlbaFontBytes(fontIndex, 0) == null) {
//                        addPointSpace();
//                    } else {
//                        addPoint(getAlbaFontBytes(fontIndex, 0), fontIndex, 0);
//                    }
//
//                } else if (chars.length > 1) {
//                    chars = FormatUtils.reverseArray(chars);
//                    for (int j = 0; j < chars.length; j++) {
//                        if (j == 0) {
//                            String valueStr = FormatUtils.bcd2Str(FormatUtils.charToByte(chars[j]));
//                            Integer fontIndex = FontTable.alaboTable.get(valueStr);
//                            if (getAlbaFontBytes(fontIndex, 3) == null) {
//                                addPointSpace();
//                            } else {
//                                addPoint(getAlbaFontBytes(fontIndex, 3), fontIndex, 3);
//                            }
//                        } else if (j == chars.length - 1) {
//                            String valueStr = FormatUtils.bcd2Str(FormatUtils.charToByte(chars[j]));
//                            Integer fontIndex = FontTable.alaboTable.get(valueStr);
//                            if (getAlbaFontBytes(fontIndex, 1) == null) {
//                                addPointSpace();
//                            } else {
//                                addPoint(getAlbaFontBytes(fontIndex, 1), fontIndex, 1);
//                            }
//
//                        } else {
//                            String valueStr = FormatUtils.bcd2Str(FormatUtils.charToByte(chars[j]));
//                            Integer fontIndex = FontTable.alaboTable.get(valueStr);
//                            if (getAlbaFontBytes(fontIndex, 2) == null) {
//                                addPointSpace();
//                            } else {
//                                addPoint(getAlbaFontBytes(fontIndex, 2), fontIndex, 2);
//                            }
//
//                        }
//                    }
//                }
//                if (i + 1 < strArray.length) {
//                    addPointSpace();
//                }
//            }


            MainCanvas paintMain = new MainCanvas();
            paintMain.showAllView(allPvList, charHeight);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private static void addPointSpace() {
        Integer fontIndex = FontTable.alaboTable.get("20");
        addPoint(getAlbaFontBytes(fontIndex, 0), 32, 0);
    }


    /**
     * 获得指定阿拉伯语的字和指定的词型状态
     *
     * @param parentValue
     * @param childValue
     * @return
     */
    public static byte[] getAlbaFontBytes(Integer parentValue, int childValue) {
        if (parentValue == null) {
            return null;
        }
        for (int i = parentValue; i < parentValue + 1; i++) {
            for (int j = childValue; j < childValue + 1; j++) {
                byte[] data = getCharData(bytes, i, j);
                if (data[0] != 0) {
                    return data;
                } else {
                    return null;
                }
            }
        }
        return null;
    }


    public static int charHeight;

    /**
     * @param arrayFontData
     * @param charCode      给定字符的ASCI码 0x20~0xFF
     * @param charStatus    0:原型 1:词头 2:词中 3:词尾
     * @return
     */
    static byte[] getCharData(byte[] arrayFontData, int charCode, int charStatus) {
        byte[] data = new byte[1]; // 新建一个包含一个元素的byte数组
        data[0] = 0;
        try {
            // 如果自库内不包含给定字符，则byte数组的第一个元素置0
            // 字符特征偏移地址
//            int offset = 0x0F;

            int fontOffset = (arrayFontData[7] & 0xff) + ((arrayFontData[8] & 0xff) << 8);

            // 取得字符高度
            charHeight = (arrayFontData[9] & 0xff) + ((arrayFontData[10] & 0xff) << 8);

            // 取得字库首字符的ASCII码
            int firstChar = (arrayFontData[11] & 0xff) + ((arrayFontData[12] & 0xff) << 8);
            // 取得字库结束字符的ASCII码
            int lastChar = (arrayFontData[13] & 0xff) + ((arrayFontData[14] & 0xff) << 8);

            // 判断给定字符是否在自库内，如果没有，退出
            if (charCode < 32 || charCode > 87) {
                return data; // 返回该数组
            }

            // 取得字库内给定字符的字符特征的地址
            int charAddr = 0x0F + (charCode + fontOffset * charStatus - firstChar) * 6;

            // 获取给定字符的字符宽度
            int charWidth = 0;
            try {
                charWidth = (arrayFontData[charAddr] & 0xff) + ((arrayFontData[charAddr + 1] & 0xff) << 8);
            } catch (ArrayIndexOutOfBoundsException e) {
                e.printStackTrace();
                return data;
            }

            int one = (arrayFontData[charAddr + 2] & 0xff);
            int two = ((arrayFontData[charAddr + 3] & 0xff) << 8);
            int three = ((arrayFontData[charAddr + 4] & 0xff) << 16);
            int four = ((arrayFontData[charAddr + 5] & 0xff) << 24);


            int charDataAddr = one + two + three + four;

            // 计算给定字符的点阵数据的总字节数
            int hightBytes = (charHeight + 7) / 8;

            int charDataSize = hightBytes * charWidth;

            //创建一个长度为点阵数据总字节数加1的byte数组
            data = new byte[charDataSize + 1];
            data[0] = (byte) charDataSize;
            System.arraycopy(arrayFontData, charDataAddr, data, 1, charDataSize);
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
            return data; // 返回该数组
        } catch (NegativeArraySizeException e) {
            e.printStackTrace();
//            return data;
        }


        return data;

    }

    /**
     * 插入需要显示的点
     *
     * @param bytes
     */
    static void addPoint(byte[] bytes, int parentIndex, int childIndex) {
        int step = 0;

        byte[] newValue = new byte[bytes[0]];

        List<Pv> pvInnerList = new ArrayList<>();
        for (int i = 0; i < (int) bytes[0]; i++) {
            newValue[i] = bytes[i + 1];
        }


        //纵向排列
        int digit = charHeight / 8;//来判断需要几个字节来表示
        int remainder = charHeight % 8;//余数
        if (remainder != 0) {
            digit++;
        }

        for (int i = 0; i < newValue.length; i += digit) {
            byte[] s1 = new byte[digit];
            for (int k = 0; k < digit; k++) {
                s1[k] = newValue[i + k];
            }
            String columnString = "";
            for (int p = s1.length - 1; p >= 0; p--) {
                byte[] b = new byte[1];
                b[0] = s1[p];
                columnString += String.valueOf(FormatUtils.bcd2Str(b));
            }
            String s = Long.toBinaryString(Long.parseLong(columnString, 16));

            int length = s.length();
            for (int index = 0; index < 8 * digit - length; index++) {
                s = "0" + s;
            }
            s = s.substring(s.length() - charHeight);

            char[] charArray = s.toCharArray();

            for (int j = 0; j < charArray.length; j++) {
                if (charArray[j] == '1') {
                    Pv point = new Pv(step, j, 1);
                    pvInnerList.add(point);
                } else {
                    Pv point = new Pv(step, j, 0);
                    pvInnerList.add(point);
                }
            }

            step++;
        }
        allPvList.add(new AllPv(parentIndex, childIndex, pvInnerList));
    }

}
